TITL DAI FIRMWARE D8FB-DAD3 V1.1 ORG :D8FB * * * * =================== *** INTERRUPT HANDLER *** * =================== * * ******************************* * INITIALISE INTERRUPT SYSTEM * ******************************* * * Initialises the interrupt system of the machine. * * Entry: No conditions. * Exit: All registers corrupted. * INTINI LXI H,:FFF8 Address int.mask register MVI A,:04 MOV M,A Only stack interrupt STA :005F Remember int. mask MVI L,:F4 MVI A,:0C MOV M,A Select ext.int. and INTA INR A MOV M,A Reset MVI A,:0C STA :01C0 Init. cursor timer MVI A,:02 STA :01C1 Init. keyboard scan counter CALL :D9A3 Reload sound timer CALL :D99D Reload keyboard timer CALL :D949 Set up int. entry points REM * Set-up interrupt vectors (also entry from utility) REM INTSU LXI H,:D9A9 SHLD :0070 Clock int. vector (7) LXI H,:D578 SHLD :006E Keyboard int. vector (6) LXI H,:C6FD SHLD :006C Screen restart vector (5) LXI H,:C6C0 SHLD :006A Math. restart vector (4) LXI H,:D755 SHLD :0068 Sound int. vector (3) LXI H,:D9E2 SHLD :0066 Stack int. vector (2) LXI H,:C70E SHLD :0064 Utility/encode vector (1) RET * * SET UP INTERRUPT VECTOR AREA: * * Sets up the vector area 0000-003F. * * Entry: No conditions. * Exit: All registers corrupted. * VECSU LXI B,:0000 Start at zero VCS10 LXI D,:D96B Startaddr. int. routine LXI H,:D973 Endaddress CALL :DE4F Transfer int. routine MOV A,C CPI :40 8 routines done? JNZ :D94C Next one if not ready LXI H,:003B Addr. highest int.vector LXI B,:FFF8 MVI D,:70 VCS20 MOV M,D Load vector addr. DCR D DCR D DAD B Calculate next addr JC :D963 Next one if not ready RET * * INTERRUPT VECTOR ROUTINE: * * During initialisation loaded into RAM on the * Restart routine locations of the CPU. * The address after LHLD is later changed into * the appropriate vector address by #D8FB. * ITMPL NOP PUSH H LHLD :0070 PCHL NOP NOP * ******************************* * DISABLE KEYBOARD INTERRUPTS * ******************************* * * Disables keyboard interrupts only. * * Entry can be different. From INTCH common part * to disable/enable sound, clock and keyboard * interrupts. * * Entry: None. * Exit: All registers preserved. * KBDI PUSH B LXI B,:BF00 Disable keyboard interrupts * INTCH PUSH PSW DI Disable interrupts LDA :005F Get current int.mask ANA B ) Calculate new one ORA C ) STA :005F Remember new mask STA :FFF8 and set mask EI Enable interrupts again POP PSW POP B RET * ****************************** * ENABLE KEYBOARD INTERRUPTS * ****************************** * * Enables keyboard interrupts only. * KBEI PUSH B LXI B,:FF40 Enable keyboard interrupts JMP :D977 Update int. mask * **************************** * DISABLE SOUND INTERRUPTS * **************************** * * Disables sound interrupts only. * SNDDI PUSH B LXI B,:F700 Disable sound interrupts JMP :D977 Update int. mask * *************************** * ENABLE SOUND INTERRUPTS * *************************** * * Enables sound interrupts only. * SNDEI PUSH B LXI B,:FF08 Enable sound interrupts JMP :D977 Update int. mask * *********************** * LOAD KEYBOARD TIMER * *********************** * * Starts a keyboard interrupt. * KBIS MVI A,:FF Init. 16.32 msec STA :FFFC Load timer 4 (keyboard) RET * ******************** * LOAD SOUND TIMER * ******************** * * Starts a sound interrupt. * SNDIS MVI A,:50 Init. 5.12 msec STA :FFFB Load timer 3 (sound) RET * *************************** * CLOCK INTERRUPT (RST 7) * *************************** * * Triggered every 20 msec by the TV page * blanking signal. * Decrements timer 01BE/BF until 0. Checks also * the contents of cursor clock timer 01C0. It is * decremented, if it becomes 0, the timer is re- * loaded and the cursor is flashed. * * Exit: All registers preserved. * CLKINT PUSH PSW PUSH B PUSH D LDA :005F Get current int. mask PUSH PSW and remember it MVI A,:04 STA :FFF8 Set stack interrupt only EI LHLD :01BE Get timer contents MOV A,H ORA L JZ :D9C2 If timer = 0 DCX H Else: SHLD :01BE decrement timer CKI10 LXI H,:01C0 Addr. cursor clock DCR M Decr. clock JNZ :D9CD Return if <>0 MVI M,:0F Load 20 ms flash time RST 5 Flash cursor DATA :12 * * GENERAL INTERRUPT RETURN: * * Restores interrupt mask and all registers. * * Entry: Interrupt mask and all registers on stack. * INTRM POP PSW Get old int. mask DI STA :FFF8 Restore int. mask STA :005F and remember it. EI POP D POP B POP PSW POP H RET * ************************** * ENABLE CLOCK INTERRUPT * ************************** * CLKEI PUSH B LXI B,:FF80 Enable clock interrupt JMP :D977 Update int.mask * ************************** * STACK INTERRUPT (RST2) * ************************** * * This routine handles an interrupt caused by the * stack overflow hardware logic. * SPINT LXI SP,:F900 Reset stackpointer XRA A STA :0117 No running inputs STA :0122 No encoding of stored line CALL :D743 Input from keyboard, reload REM timers sound/keyb EI MVI A,:16 JMP :D9F5 Run error 'STACK OVERFLOW' * * * * * =============== *** ERROR HANDLER *** * =============== * * ****************** * ERROR HANDLING * ****************** * * Produces an error message and other information * about errors. * * Entry: A: Error message number. * BC: Latest position in EBUF or textbuffer. * Exit: If during input: Restart input statement. * If during encoding: Back to ELINA (C93C) * for handling. * Else: Restart Basic (direct mode). * ERROR MOV B,A Save error pointer XRA A STA :0131 Set output screen/RS232 CALL :CEE4 Select ROM bank 0 DBL :0000 NOP NOP LDA :0118 Get RUNF ORA A JNZ :DA3D If run-time error JMP :DA64 If compile-time error * * ENTRYPOINTS TO ERROR ROUTINES: * ERRSN MVI A,:17 JMP :D9F5 Run 'SYNTAX ERROR' * ERROM MVI A,:13 JMP :D9F5 Run 'OUT OF MEMORY' * ERRRA MVI A,:09 JMP :D9F5 Run 'NUMBER OUT OF RANGE' * ERRTM MVI A,:14 JMP :D9F5 Run 'TYPE MISMATCH' * ERROV MVI A,:03 JMP :D9F5 Run 'OVERFLOW' * ERRD0 MVI A,:06 JMP :D9F5 Run 'DIVISION BY ZERO' * ERRBS MVI A,:05 JMP :D9F5 Run 'SUBSCRIPT ERROR' * ERRNF MVI A,:00 JMP :D9F5 Run 'NEXT WITHOUT FOR' * ERREL MVI A,:12 JMP :D9F5 Run 'ERROR LINE RUN' * ERRLS MVI A,:08 JMP :D9F5 Run 'STRING TOO LONG' * ****************** * RUN-TIME ERROR * ****************** * ERRRU CALL :DA50 Print error message LDA :0117 Get RDIPL ORA A JNZ :DA4D Jump if running inputs CALL :DA75 else: Print 'IN LINE ' JMP :C814 Re-enter BASIC REM * If error in input: REM ERT10 JMP :E350 (0) Back to restart input * *********************** * PRINT ERROR MESSAGE * *********************** * * Entry: B: Error message number. * Exit: BC preserved, AFDEHL corrupted. * ERRMS CALL :DD55 Cursor to begin (next) line MOV A,B Get error number LXI H,:DA94 Base of list error messages ADD A Multiply error nr *2 MOV E,A and save offset MVI D,:00 DAD D Calculate table addr. MOV E,M ) Get addr of message INX H ) in DE MOV D,M ) XCHG and in HL CALL :DAD4 Print error message RET * ********************** * COMPILE-TIME ERROR * ********************** * * Handles errors in direct mode. Only an error * message is printed. Control is passed back to * ELINA (C93C) except if it is an error during * encoding of a stored line. * * Entry: A: Error number. * C: Points to last read character on * input line. * Exit: To Basic interpreter. * ERRCO LDA :0122 Get ERSFL CPI :01 Error during encoding? JZ :C957 Then handle error REM * Error in direct command: REM CALL :DA50 Print error message CALL :DD5E Print car.ret JMP :C823 Restart interpreter * REM ******************************************** * PRINT LINE NUMBER IN WHICH ERROR OCCURED * ******************************************** * * Prints car.ret if current line is a direct command. * Else, prints 'IN LINE ' and car.ret. * * Entry: None. * Exit: ABCDEHL preserved. F corrupted. * Z=1: direct command. * MSGIL PUSH H PUSH PSW LHLD :0100 Get start current line MOV A,H ORA L Check if 0 PUSH PSW JZ :DA8C If direct, print car.ret CALL :DAFF Else, print 'IN LINE' DBL :DB7F MOV A,M ) Get line nr in HL INX H ) MOV L,M ) MOV H,A ) CALL :EFB4 (0) Print line number MIL10 CALL :DD5E Print car.ret POP PSW POP H MOV A,H POP H RET * ************************************ * ERROR MESSAGES INDIRECTION TABLE * ************************************ * * The address points to the location where the * string with the error messages can be found. * Between brackets the error number. * * Run-time errors: *ERITB E?NF DBL :DC1C (00) NEXT WITHOUT FOR E?RG DBL :DC2C (01) RETURN WITHOUT GOSUB E?OD DBL :DC33 (02) OUT OF DATA E?OV DBL :DC3E (03) OVERFLOW E?US DBL :DC50 (04) UNDEFINED LINE NUMBER E?BS DBL :DC5C (05) SUBSCRIPT ERROR E?D0 DBL :DC68 (06) DIVISION BY ZERO E?OS DBL :DC95 (07) OUT OF STRING SPACE E?LS DBL :DC9D (08) STRING TOO LONG E?RA DBL :DCD8 (09) NUMBER OUT OF RANGE E?IN DBL :DCB2 (0A) INVALID NUMBER E?LO0 DBL :DCFA (0B) LOADING ERROR 0 E?LO1 DBL :DCFE (0C) LOADING ERROR 1 E?LO2 DBL :DD02 (0D) LOADING ERROR 2 E?LO3 DBL :DD06 (0E) LOADING ERROR 3 E?UA DBL :DCF1 (0F) UNDEFINED ARRAY E?NC DBL :DCC2 (10) COLOUR NOT AVAILABLE E?OF DBL :DCB7 (11) OFF SCREEN E?EL DBL :DD12 (12) ERROR LINE RUN REM * Compile/Run-time errors: REM E?OM DBL :DC47 (13) OUT OF MEMORY E?TM DBL :DC8A (14) TYPE MISMATCH E?LN DBL :DCD6 (15) LINE NUMBER OUT OF REM . RANGE E?SO DBL :DC38 (16) STACK OVERFLOW REM * Compile-time errors: REM E?SN DBL :DC23 (17) SYNTAX ERROR E?ID DBL :DC79 (18) COMMAND INVALID E?CN DBL :DCA9 (19) CAN'T CONT E?TC DBL :DCE3 (1A) LINE TOO COMPLEX E?ST DBL :DC47 (1B) OUT OF MEMORY * ******************************* * WAIT; part of RTALK (0EC6D) * ******************************* * * Entry: HL: Wait time. * REM * If wait: * As old routine, but HL replaced by DE. REM RTK20 DCX D ] MOV A,D ] ORA E ] JNZ :DACC ] Wait for DE=0 RET ] DATA :FF ] * * * UNL ERITB EQU E?NF LST END